#include "address.h"
#include "xdebug.h"
#include "common.h"

Address*
addr_new()
{
    Address *addr;
    
    addr = emalloc(sizeof(Address));
    memset(addr, 0, sizeof(Address));
    
    return addr;
}

void
addr_delete(Address* addr)
{
    if (NULL == addr)
        return;
   
    addr_clear(addr);
    efree(addr);
}

void 
addrs_delete_all(GSList *slist)
{
    Address *addr;
    GSList  *root = slist;

    while (slist) {
        addr = slist->data;
        addr_delete(addr);
        slist = g_slist_next(slist);
    }

    if (root) {
        g_slist_free(root);
    }
}

void
addr_clear(Address* addr)
{
    if (NULL == addr)
        return;
    SAFE_FREE(addr->user);
    SAFE_FREE(addr->domain);
    SAFE_FREE(addr->name);
}

void addrs_print(GSList* slist)
{
    Address *addr;

    while (slist) {
        addr = slist->data;
        printf("user:%s, domain:%s, name:%s\n", addr->user, addr->domain, addr->name);
        slist = g_slist_next(slist);
    }
}


GSList*
addr_parse(const char* addrstr)
{
    char    *astr, *startstr, *endstr, *tmp, *spstr, *laststr;
    int     addrlen;
    int     slen, flen, tlen;
    Address *addr = NULL;
    GSList  *slist = NULL;

    if (NULL == addrstr)
        return NULL;
 
    slen = strlen(addrstr);
    laststr = addrstr + slen;
    astr = addrstr;
    flen = slen; // 查找的长度
    INFO("astr: %p, %s, len:%d, end:%p\n", astr, astr, slen, addrstr+slen); 
    while (1)
    {
        flen = addrstr + slen - astr;
        INFO("slen: %d, %d, flen: %d\n", slen, addrstr-astr, flen);
        startstr = strchr(astr, '@');
        if (NULL == startstr) {
            INFO("not found @ !\n");
            break;
        }
        INFO("found @ !!\n");
        addr = addr_new();
       
        // 查找,
        //　要注意这样的格式 <"Undisclosed-Recipient:;"@mail3.1stchina.net>
        spstr = strchr(astr, ',');
        if (NULL == spstr) {
            //spstr = strchr(astr, ';');
            //if (NULL == spstr) {
                spstr = addrstr + slen;
            //}else{
            //    flen = spstr - astr;
            //}
        }else{
            flen = spstr - astr;
        }
        // 避免 zhaowei@zhaowei.com <zhaowei@zhaowei.com> 这样的被解析错 
        INFO("try found <: %p, %s\nflen: %p, %d\n", astr, astr, astr+flen, flen);
        tmp = xstrnchr(astr, flen, '<');
        if (NULL != tmp) {
            INFO("found < ...%p, %s, len: %d\n", tmp, tmp, spstr-tmp);
            startstr = xstrnchr(tmp, spstr-tmp, '@');
            INFO("xstrnchr: %p\n", startstr);
        }

        endstr = startstr; 
        // 查找 user
        INFO("find user: %p,%s\n", startstr, startstr);
        while (startstr >= astr) {
            if (*startstr <= 32 || *startstr == '\"' || *startstr == '<' || *startstr == ',' || *startstr == ';') {
                startstr++;
                break;
            }
            startstr--;
        }
        if (startstr < astr)
            startstr = astr;
        addr->user = xstrndup(startstr, endstr-startstr); 
        INFO("user: %s\n", addr->user);
        // 查找 name
        startstr--;
        while (startstr >= astr && (*startstr <= 32 || *startstr == '\t' || *startstr == '"' || *startstr == '<')) startstr--;
        
        startstr++;

        if (startstr > astr) {
            tmp = startstr;
            if (*startstr == '"') startstr--;
            INFO("tmp: %s, %c, %d, %p, %p\n", tmp, *tmp, *tmp, startstr, astr);
            while (startstr >= astr) {
                if (*startstr == '"') {
                    startstr++;
                    break;
                }
                startstr--; 
            }
            if (startstr < astr)
                startstr = astr;
            tlen = tmp-startstr;
            startstr = xstrnstrip(startstr, &tlen);

            addr->name = xstrndup(startstr, tlen);
            INFO("name: %s\n", addr->name);
        }
        // 查找 domain
        startstr = endstr + 1;
        INFO("endstr: %p\n", endstr);
        while (endstr < laststr && *endstr) {
            if (*endstr <= 32 || *endstr == '"' || *endstr == '>' || *endstr == ',' || *endstr == ';') {
                //endstr--;
                break;
            }
            endstr++;
            printf("%c %x ", *endstr, *endstr);
        }
        addr->domain = xstrndup(startstr, endstr-startstr);
        INFO("domain: %s\n", addr->domain); 
        slist = g_slist_append(slist, addr);

        while (*endstr && *endstr != ',' && *endstr != ';') endstr++;
        if (0 == *endstr) {
            break;
        }

        endstr++;
        astr = endstr + 1;
    }
    INFO("slist size: %d\n", g_slist_length(slist));
    return slist;
}

void 
addr_set(Address *addr, char* u, char *d, char *n)
{
    if (NULL == addr)
        return;

    SAFE_FREE(addr->user);
    addr->user = xstrdup(u);

    SAFE_FREE(addr->domain);
    addr->domain = xstrdup(d);

    SAFE_FREE(addr->name);
    addr->name = xstrdup(n);
}

int
addr_string(Address* addr, char *save, int slen)
{
    int len;
    
    if (NULL == addr)
        return -1;
    if (NULL == addr->user || NULL == addr->domain) 
        return -2;

    if (addr->name != NULL) {
        snprintf(save, slen, "\"%s\" <%s@%s>", addr->name, addr->user, addr->domain);
    }else{
        snprintf(save, slen, "<%s@%s>", addr->user, addr->domain);
    }

    return 0;
    
}


#ifdef MAIN_TEST_ADDR

GHashTable  *gmemhash;
int main()
{
    GSList  *slist;
    char *test = "zhaowei <zhaowei@zhaowei.com>,rabbit_haobobo <rabbit_haobobo@163.com>";    
    char *test1 = "\"dev_list\" <dev_list@eyou.net>,\r\n \"sanco\" <sanco@eyou.net>,\r\n \"zhangqiao\" <zhangqiao@zhanzuo.net>";
    char *test2 = "<bcxbcx@21cn.com>, <williamb@public.nc.jx.cn>, <bichengxiao@21cn.com>,\n        <jxtech@public.nc.jx.cn>";
    char *test3 = "srzhtx@sr.jiangxi.cn, srzry@sr.jiangxi.cn, srwyj@sr.jiangxi.cn,\n\tsrlxl@sr.jiangxi.cn, srccy@sr.jiangxi.cn, srsfmsk@sr.jiangxi.cn,\n\tsrsfzhk@sr.jiangxi.cn, srsfnyk@sr.jiangxi.cn, srsfcmk@sr.jiangxi.cn,\n\tsrsfxzk@sr.jiangxi.cn, srsfgyk@sr.jiangxi.cn, srsfwwk@sr.jiangxi.cn,\n\tsrsfrxb@sr.jiangxi.cn, srsfdck@sr.jiangxi.cn, srsfcjk@sr.jiangxi.cn,\n\tsrsfjcs@sr.jiangxi.cn, srsfjsk@sr.jiangxi.cn, \n\tsrsfswk@sr.jiangxi.cn,\n\tsrxtl@sr.jiangxi.cn, srzzc@sr.jiangxi.cn, srhhp@sr.jiangxi.cn,\n\tsrczx@sr.jiangxi.cn, srcjp@sr.jiangxi.cn, \n\tsrxjb@sr.jiangxi.cn,\n\tsrtrp@sr.jiangxi.cn, srzxp@sr.jiangxi.cn, srhqs@sr.jiangxi.cn,\n\tsrwbz@sr.jiangxi.cn, srlqr@sr.jiangxi.cn, \n\tsrzyd@sr.jiangxi.cn,\n\tsrcjh@sr.jiangxi.cn, srwjp@sr.jiangxi.cn, srzrh@sr.jiangxi.cn,\n\txzqwb@163.com, xzhqzhfb@163.com, hum@srgov.cn, \n\tsrx@srx.gov.cn,\n\tgfxwb@srgov.cn, xulihuo@srgov.cn, ysxwb@srgov.cn, ysxzfb@srgov.cn,\n\tyansxwb@srgov.cn, zfb@yszw.net, yyxw@srgov.cn, \n\tyyzf@srgov.cn,\n\thfxwb@tom.com, srhfzfb@sina.com, dxsw@srgov.cn,\n\tdexingzfb@yahoo.com.cn, 13803594055@00172.com, wygov123@yahoo.com.cn,\n\tygxwb@srgov.cn, yugangov@srgov.cn, wnxwmsk@sr.jiangxi.cn,\n\twnxmsk@sr.jiangxi.cn, pyxw@srgov.cn, pyxzfb@sohu.com, stbz@srgov.cn,\n\tsrszdw@srgov.cn, sjsz@srgov.cn, public@srgov.cn";

    INFO("test: %s\n", test3);
    INFO(" begin ... \n"); 
    gmemhash = e_init(NULL);

    INFO("parse addr ...\n");
    slist = addr_parse(test3);

    INFO("parse over ...\n");
    if (NULL != slist) {
        addrs_print(slist);
    }
    
    addrs_delete_all(slist);
    e_destroy(gmemhash);
    return 0;
}

#endif


